using System;
using System.Collections.Generic;
using System.Text;

using Mud.Common.Messages;
using Mud.Common.Physical;
using Mud.Common;

namespace Mud.Server.Physical
{
    /// <summary>
    /// This type of controler serves events to the client.
    /// </summary>
    public class ClientCreatureControler : CreatureControler
    {

        /// <summary>
        /// Controler client.
        /// </summary>
		public Client.IClient Client
        {
            get { return _client; }
        }
		private Client.IClient _client;


		public ClientCreatureControler(Client.IClient client)
        {
            if (client == null)
                throw new ArgumentNullException("client");
            _client = client;
        }

        #region Event receiver overrides


        public override void Receive(EventCreatureAppeared e)
        {
            MessageEventCreatureAppeared msg = new MessageEventCreatureAppeared();
            msg.Creature = ObjectToMessageMapper.MapToMessage(this.ControledCreature, e.Source);
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureDisappeared e)
        {
            MessageEventCreatureDisappeared msg = new MessageEventCreatureDisappeared();
            msg.CreatureId = e.Source.ObjectId;
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureMoveStarted e)
        {
            MessageEventCreatureStartedMoving msg = new MessageEventCreatureStartedMoving();
            msg.CreatureId = e.Source.ObjectId;
            msg.X = e.TargetPosition.X;
            msg.Y = e.TargetPosition.Y;
            msg.MovementType = e.MovementType;
            msg.Duration = e.Duration;
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureMoveEnded e)
        {
           
            MessageEventCreatureEndedMoving msg = new MessageEventCreatureEndedMoving();
            msg.CreatureId = e.Source.ObjectId;
            msg.X = e.TargetSquare.X;
            msg.Y = e.TargetSquare.Y;
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureSay e)
        {
                MessageEventCreatureSay msg = new MessageEventCreatureSay();
                msg.SourceCreatureId = e.Source.ObjectId;
                msg.SayType = e.CommunicationType;
                if (e.Target != null)
                    msg.TargetObjectId = e.Target.ObjectId;
                this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureEnteredArea e)
        {

            if (e.Source == this.ControledCreature) // this is me!, I need to get my bearings
            {

                // area info
                MessageEventAreaChanged areaInfo = new MessageEventAreaChanged();
                areaInfo.Area.AreaName = e.Area.Name;
                areaInfo.Area.AreaXDimension = e.Area.AreaSize.Width;
                areaInfo.Area.AreaYDimension = e.Area.AreaSize.Height;
                this.Client.EventQueue.Enqueue(areaInfo);

                // land part
                MessageEventAreaLandChanged landInfo = new MessageEventAreaLandChanged();
                int perceivedAreaSize = this.ControledCreature.Sensors.VisualSenseStrength;

                Rectangle perceivedArea = new Rectangle(0,0, e.Area.AreaSize.Width, e.Area.AreaSize.Height); 

                landInfo.Land.XOffset = perceivedArea.X;
                landInfo.Land.YOffset = perceivedArea.Y;
                landInfo.Land.Width = perceivedArea.Width;
                landInfo.Land.Height = perceivedArea.Height;

                landInfo.Land.Terrain = new TerrainType[perceivedArea.Width, perceivedArea.Height];
                for (int x = perceivedArea.X; x < perceivedArea.Right; x++)
                    for (int y = perceivedArea.Y; y < perceivedArea.Bottom; y++)
                    {
                        landInfo.Land.Terrain[x - perceivedArea.X, y - perceivedArea.Y] = e.Area.Land[x, y].Terrain;
                    }
                this.Client.EventQueue.Enqueue(landInfo);
            }

            MessageEventCreatureEnteredArea msg = new MessageEventCreatureEnteredArea();
            msg.AreaName = e.Area.Name;
            msg.Creature = ObjectToMessageMapper.MapToMessage(this.ControledCreature, e.Source);
            this.Client.EventQueue.Enqueue(msg);

        }

        public override void Receive(EventCreatureExitedArea e)
        {
            MessageEventCreatureExitedArea msg = new MessageEventCreatureExitedArea();
            msg.AreaName = e.Area.Name;
            msg.CreatureId = e.Source.ObjectId;
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventSimpleObjectAppeared e)
        {
            MessageEventSimpleObjectAppeared msg = new MessageEventSimpleObjectAppeared();
            msg.SimpleObject = ObjectToMessageMapper.MapToMessage(this.ControledCreature, e.Source);
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventSimpleObjectDisappeared e)
        {
            MessageEventSimpleObjectDisappeared msg = new MessageEventSimpleObjectDisappeared();
            msg.SimpleObjectId = e.Source.ObjectId;
            this.Client.EventQueue.Enqueue(msg);
        }

        public override void Receive(EventCreatureTurned e)
        {
            MessageEventCreatureTurned msg = new MessageEventCreatureTurned();
            msg.CreatureId = e.Source.ObjectId;
            msg.Direction = e.Direction;
            this.Client.EventQueue.Enqueue(msg);
        }
        
        
        public override void Receive(EventLocationSay e)
        {
            MessageEventLocationSay msg = new MessageEventLocationSay();
            msg.X = e.Location.X;
            msg.Y = e.Location.Y;
            msg.SayType = e.CommunicationType;
            this.Client.EventQueue.Enqueue(msg);
        }

        #endregion

 
    }
}
